//! Copyright (c) 2005-2008, Simon Howard
//! Permission to use, copy, modify, and/or distribute this software for any purpose
//! with or without fee is hereby granted, provided that the above copyright notice
//! and this permission notice appear in all copies.
//! THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
//! REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
//! FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
//! INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
//! OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
//! TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
//! THIS SOFTWARE.

#![allow(dead_code)]

const NUM_TEST_VALUES: usize = 200;

/// Hash function for pointers.
fn pointer_hash(ptr: *const i32) -> usize {
    ptr as usize
}

/// Hash function for integers.
fn int_hash(value: &i32) -> usize {
    *value as usize
}

/// Case-sensitive hash function for strings.
fn string_hash(s: &str) -> usize {
    s.chars().fold(0, |acc, c| acc.wrapping_add(c as usize))
}

/// Case-insensitive hash function for strings.
fn string_nocase_hash(s: &str) -> usize {
    s.chars().fold(0, |acc, c| acc.wrapping_add(c.to_ascii_lowercase() as usize))
}

#[test]
fn test_pointer_hash() {
    let array = [0; NUM_TEST_VALUES];

    for i in 0..NUM_TEST_VALUES {
        for j in (i + 1)..NUM_TEST_VALUES {
            assert_ne!(pointer_hash(&array[i]), pointer_hash(&array[j]));
        }
    }
}

#[test]
fn test_int_hash() {
    let array = (0..NUM_TEST_VALUES).collect::<Vec<i32>>();

    for i in 0..NUM_TEST_VALUES {
        for j in (i + 1)..NUM_TEST_VALUES {
            assert_ne!(int_hash(&array[i]), int_hash(&array[j]));
        }
    }

    let i = 5000;
    let j = 5000;
    assert_eq!(int_hash(&i), int_hash(&j));
}

#[test]
fn test_string_hash() {
    let test1 = "this is a test";
    let test2 = "this is a tesu";
    let test3 = "this is a test ";
    let test4 = "this is a test";
    let test5 = "This is a test";

    assert_ne!(string_hash(test1), string_hash(test2));
    assert_ne!(string_hash(test1), string_hash(test3));
    assert_ne!(string_hash(test1), string_hash(test5));
    assert_eq!(string_hash(test1), string_hash(test4));
}

#[test]
fn test_string_nocase_hash() {
    let test1 = "this is a test";
    let test2 = "this is a tesu";
    let test3 = "this is a test ";
    let test4 = "this is a test";
    let test5 = "This is a test";

    assert_ne!(string_nocase_hash(test1), string_nocase_hash(test2));
    assert_ne!(string_nocase_hash(test1), string_nocase_hash(test3));
    assert_eq!(string_nocase_hash(test1), string_nocase_hash(test5));
    assert_eq!(string_nocase_hash(test1), string_nocase_hash(test4));
}

fn main() {
    // Run tests using the Rust test framework
    // Note: This function is not necessary in Rust as tests are automatically discovered.
    // Use `cargo test` to run the tests.
}
